
public class Bag {
	
	/**
	 * A 'bag' that contains user inputted strings.
	 * 
	 * @author James Stanier
	 * @version 13/11/2005
	 */
	/*;
	 !open *Field declarations* 
	 The function of this class is to abstractly represent a "bag". The field declarations
	 define an array to represent the bag, with the slots of the array representing spaces
	 inside. Here, the |bag| variable is declared.
	 ;*/
	private String[] bag;
	private int nextFree = 0;
	/*;

	 The integer |nextFree| is a count of the next free slot in the bag, which can be
	 any number from $0-n$ where $n$ represents the |capacity| of the bag.  
	 ;*/
	
	/**
	 * Construct a new bag object.
	 * 
	 * @param   capacity    The capacity of the bag.
	 */
	/*;
	 !open *Constructor*
	 The |constructor| defines what properties the object takes upon |instantiation|; when
	 an object of that class is created. 
	 ;*/
	public Bag(int capacity)
	{
		bag = new String[capacity];
	}
	/*;
	 !shut Here, the constructor is passed a |parameter| which is the capacity $n$, the integer
	 that will be the size of the bag. The array is then instantiated at this given size.
	 ;*/
	
	/**
	 * Add a string to the bag. If the bag is full, then a message is displayed.
	 * 
	 * @param  s   The user inputted string.
	 * @return     Exit the loop when the string is inputted.
	 */
	/*;
	 !open *Adding a string to the bag*
	 This method will add a given string, |s|, to the bag. A check is made in the conditional
	 if statement: nextFree\neq bag.length$, to check that the bag isn't full. This is because
	 |nextFree| increases in size every time a string is added to the bag. If the bag isn't full,
	 then the slot signified by $nextFree$, $bag[nextFree]$, is filled with the given string, and
	 $nextFree$ is incremented.
	 ;*/
	public void add(String s)
	{
		if(nextFree != bag.length) {
			bag[nextFree] = s;
			nextFree++;
		}
		else {
			System.out.println("Sorry, this bag is full!");
		}
	}
	/*;
	 !shut If the |bag| is full ($nextFree=bag.length$) then a message is printed to the |console|, 
	 informing that the bag is full. 
	 ;*/
	
	/**
	 * Check whether the bag is full.
	 * 
	 * @return  Whether the bag is full (true).
	 */
	/*;
	 !open *Checking whether the bag is full*
	 It may be useful to check if the bag is full before adding anything. Therefore, this method
	 returns a |boolean| value, (i.e. true or false) whether it is or not. When the method is called,
	 a check is made whether $nextFree=bag.length$. If it is, this means that |nextFree|, indicating
	 the next free slot in the bag has incremented to the same size as the bag array and it is full.
	 This is because the $length$ command returns the length of the array starting at the index of $1$,
	 whereas the actual |array indexing begins at $0$. If an insertion was made here at |nextFree|,
	 then it would cause an |null pointer exception| as it would try and access a slot in the array that
	 does not exist.
	 ;*/
	public boolean isFull()
	{
		if(nextFree == bag.length) {
			return true;
		}
		return false;
	}
	/*;
	 !shut True is returned if the bag is full, and false is returned if the bag is not. This is an ideal way
	 to prevent incorrect insertions into the bag.
	 ;*/
	
	/**
	 * Check if a certain string exists within the array.
	 * 
	 * @param   s   User inputted string to be checked in the array.
	 */
	public boolean contains(String s)
	{
		/*;
		 !open *Searching for an item*
		 The ability to |search| for an item in the bag is useful. This can be done fairly
		 simply with a for loop, such as the one presented below. The loop iterates through
		 the entire bag, as signified by starting at the index $0$, looping while $i<bag.length$,
		 and incrementing $i$ until this guard is met.
		 ;*/
		for(int i = 0; i < bag.length; i++) {
			if(bag[i] == s) {
				return true;
			}
		}
		return false;
		/*;
		 !shut The check made at each increment of $i$ is whether $i$th element in the list is equal
		 to $s$, the string passed in as the |formal parameter| of the method. If at any point $bag[i]=s$,
		 then true is returned. Else, if it is not found, the loop fully |iterate|s over the whole bag
		 and the statement to return false is reached, and that is returned.
		 ;*/
	}
	
	/**
	 * Remove a string from the array.
	 * 
	 * @param   s   String to be removed from the array.
	 * @return  Finish the loop if the string is removed.
	 */
	public void remove(String s)
	{
		/*;
		 !open *Modifying search: removing a string*
		 By using the search function and slightly modifiying it, it is possible to write some code
		 that will look for a given string in the bag, and if it is present, set that position of the 
		 array to |null|, thus removing it from the array.
		 ;*/
		for(int i = 0; i < bag.length; i++) {
			if(bag[i] == s) {
				bag[i] = null;
				return;
			}
		}
		System.out.println("This string is not contained in the array.");
		/*;
		 !shut If the string given is not found in the array, then a message is printed to show that this is
		 the case.
		 ;*/
	}
	
	
	/*;
	 !open *Printing the bag to the terminal*
	 By using the for loop construct as before, it is simple to |iterate| through the entire bag
	 and at each element $i$ print out the string that is stored there.
	 ;*/
	public void showStrings()
	{   
		for(int i = 0; i < bag.length; i++) {
			System.out.println(bag[i]);
		}
	}
	/*;
	 !shut Loops are very important structures in programming - they can be used for a variety of purposes
	 as seen in this class! 
	 ;*/
}
